using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace roster.Domain
{
    public class LootList : ILootList
    {
        private List<IPlayer> m_Players = new List<IPlayer>();

        public LootList(IEnumerable<IPlayer> players)
        {
            m_Players.AddRange(players);
        }

        public LootList()
        {
        }

        #region ILootList Members

        public IEnumerable<IPlayer> Players
        {
            get { return new List<IPlayer>(m_Players); }
        }

        public void AddPlayer(IPlayer player)
        {
            m_Players.Add(player);
        }

        public void RemovePlayer(IPlayer player)
        {
            m_Players.Remove(player);
        }

        public void MovePlayerUp(IPlayer player)
        {
            int currentPosition = m_Players.IndexOf(player);
            if (AtTopOfList(currentPosition))
            {
                m_Players.Remove(player);
                m_Players.Insert(--currentPosition, player);
            }
        }

        public void MovePlayerDown(IPlayer player)
        {
            int currentPosition = m_Players.IndexOf(player);
            if (AtBottomOfList(currentPosition))
            {
                m_Players.Remove(player);
                m_Players.Insert(++currentPosition, player);
            }
        }

        public void Suicide(IPlayer player)
        {
            m_Players.Remove(player);
            m_Players.Add(player);
        }

        public void Update(IEnumerable<IPlayer> mergeList)
        {
            foreach (IPlayer player in mergeList)
            {
            	if (m_Players.Contains(player) == false)
            		m_Players.Add(player);
            }
        	
            var combinedList = new List<IPlayer>();
            IEnumerator<IPlayer> mergeEnumerator = mergeList.GetEnumerator();
            foreach (IPlayer player in m_Players)            
            {
                if(mergeList.Contains(player))
                {
                    mergeEnumerator.MoveNext();
                    combinedList.Add(mergeEnumerator.Current);           
                }          
                else
                {
                    combinedList.Add(player);
                }
            }
            m_Players = combinedList;
        }

        IEnumerator<IPlayer> IEnumerable<IPlayer>.GetEnumerator()
        {
            return m_Players.GetEnumerator();
        }

        public IEnumerator GetEnumerator()
        {
            return ((IEnumerable<IPlayer>) this).GetEnumerator();
        }

        public void Clear()
        {
            m_Players.Clear();
        }

        public void Randomize()
        {
            var m_RandomizedPlayerList = new List<IPlayer>();
            var rnd = new Random();

            while(m_Players.Count > 0)
            {
                int index = rnd.Next(m_Players.Count);
                m_RandomizedPlayerList.Add(m_Players[index]);
                m_Players.RemoveAt(index);
            }

            m_Players = m_RandomizedPlayerList;
        }

        public void AddPlayers(IEnumerable<IPlayer> players)
        {
            foreach (IPlayer player in players)
            {
                AddPlayer(player);
            }
        }

        #endregion

        private static bool AtTopOfList(int currentPosition)
        {
            return currentPosition > 0;
        }

        private bool AtBottomOfList(int currentPosition)
        {
            return currentPosition != (m_Players.Count - 1);
        }
    }
}